package com.irdstudio.efp.esb.api.rest.sed.credit;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.util.Data2Zh;
import com.irdstudio.basic.framework.core.util.DateTool;
import com.irdstudio.basic.framework.core.util.StringUtil;
import com.irdstudio.basic.framework.core.util.TraceUtil;
import com.irdstudio.efp.console.service.facade.SOrgService;
import com.irdstudio.efp.console.service.vo.SOrgVO;
import com.irdstudio.efp.cus.service.facade.CusIndivService;
import com.irdstudio.efp.cus.service.facade.CusWhiteListEService;
import com.irdstudio.efp.cus.service.facade.OrgWhiteListEService;
import com.irdstudio.efp.cus.service.vo.CusIndivVO;
import com.irdstudio.efp.cus.service.vo.CusWhiteListEVO;
import com.irdstudio.efp.cus.service.vo.OrgWhiteListEVO;
import com.irdstudio.efp.esb.api.bean.sed.credit.req.ReqContractEleAcqBean;
import com.irdstudio.efp.esb.api.bean.sed.credit.resp.RespContractEleAcqBean;
import com.irdstudio.efp.esb.api.common.EsbRespServiceBeanCreator;
import com.irdstudio.efp.esb.common.constant.EsbBizEnums;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.common.server.req.EsbReqServiceBean;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.limit.service.facade.LmtPrdContService;
import com.irdstudio.efp.limit.service.vo.LmtPrdContVO;
import com.irdstudio.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.irdstudio.efp.nls.service.vo.sx.NlsCreditInfoVO;
import com.irdstudio.efp.rule.service.facade.TaxIncomeTaxInfoService;
import com.irdstudio.efp.rule.service.facade.TaxWithholdRemitCorpService;
import com.irdstudio.efp.rule.service.vo.TaxIncomeTaxInfoVO;
import com.irdstudio.efp.rule.service.vo.TaxWithholdRemitCorpVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Objects;

/**
 * 
  * TODO 合同要素查询
  * @author wanglihua
  * @since 2019年4月18日 下午3:41:13
  * @version 1.0
 */
@RestController
@RequestMapping("/esb")
public class ContractEleAcqController {
	
	private static Logger logger = LoggerFactory.getLogger(ContractEleAcqController.class);
	
	@Autowired
	@Qualifier("nlsCreditInfoService")
	private NlsCreditInfoService nlsCreditInfoService;
	
	@Autowired
	@Qualifier("cusIndivService")
	private CusIndivService cusIndivService;
	
	@Autowired
	@Qualifier("lmtPrdContService")
	private LmtPrdContService lmtPrdContService;
	
	@Autowired
	@Qualifier("sOrgService")
	private SOrgService sOrgService;
	
	@Autowired
	@Qualifier("cusWhiteListEService")
	private CusWhiteListEService cusWhiteListEService;
	
	@Autowired
	@Qualifier("orgWhiteListEService")
	private OrgWhiteListEService orgWhiteListEService;
	
	@Autowired
    @Qualifier("taxIncomeTaxInfoService")
	private TaxIncomeTaxInfoService taxIncomeTaxInfoService;
	
	@Autowired
    @Qualifier("taxWithholdRemitCorpService")
	private TaxWithholdRemitCorpService taxWithholdRemitCorpService;

	@ModelAttribute("esbReqServiceBean")
	public EsbReqServiceBean getReqEsbHeadBean(HttpServletRequest request) {
		logger.info("获取ESB请求对象，校验 ESB请求系统头和请求应用头对象开始");
		EsbReqServiceBean esbReqServiceBean = (EsbReqServiceBean) request.getAttribute("esbReqServiceBean");
		return esbReqServiceBean;
	}

	@ModelAttribute("reqContractEleAcqBean")
	public ReqContractEleAcqBean getReqEsbBodyBean(HttpServletRequest request) {
		logger.info("获取合同要素查询接口请求对象，校验合同要素查询接口请求体对象开始");
		String esbReqBody = (String) request.getAttribute("esbReqBody");
		return JSONObject.parseObject(esbReqBody, ReqContractEleAcqBean.class);
	}
	
	@PostMapping("/SERVICE_30230006_01")
	public EsbRespServiceBean doRecv(@Validated @ModelAttribute("esbReqServiceBean") EsbReqServiceBean esbReqServiceBean, BindingResult br1,
                                     @Validated @ModelAttribute("reqContractEleAcqBean") ReqContractEleAcqBean reqContractEleAcqBean, BindingResult br2, Exception exception) {
		String lmtApplySeq = reqContractEleAcqBean.getCrdtAppFlowNo();
		String certType = reqContractEleAcqBean.getCertTp();
		String certNo = reqContractEleAcqBean.getCertNo();
		String globalSerno = esbReqServiceBean.getSysHead().getGlblSrlNo();
		TraceUtil.setTraceId(globalSerno);
		logger.info("***********合同要素查询接口处理开始***********授信申请流水号:"+lmtApplySeq);
		RespContractEleAcqBean result = new RespContractEleAcqBean();
		try {
			// 通过切面校验个人用信申请查询请求参数是否正确，如不正确则返回错误信息
			if (Objects.nonNull(exception)) {
				throw exception;
			}
			
			//根据OriTxnFlowNo查询授信表
			NlsCreditInfoVO creditInfo = queryCreditInfoRs(lmtApplySeq);
			if(Objects.nonNull(creditInfo)) {
				//判断该授信申请是不是该客户名下的授信
				boolean isCertEqual = whetherCertEqual(creditInfo,certType,certNo);
				if(!isCertEqual) {
					throw new BizException(EsbRetCodeStandard.KHXXJYBTG.getValue(),"该笔授信不属于该证件号和证件类型所对应的客户！");
				}
				//根据授信流水号查询纳税信息表，得到扣缴义务人识别号
				String wthldngAgntNo = getWthldngAgntNo(lmtApplySeq);
				//根据扣缴义务人识别号查询代扣代缴单位信息表，得到代扣代缴单位名称
				String wthldngCorpNm = getWthldngCorpRgstTpNm(wthldngAgntNo,lmtApplySeq);
				//通过查询授信信息表得到网贷经办机构
				String nlsOperOrgid = getnlsOperOrgid(reqContractEleAcqBean);
				//通过网贷经办机构查询机构表
				SOrgVO result1 = queryOrgIdRs(nlsOperOrgid);
				//初始化客户白名单、机构白名单的结果对象
				CusWhiteListEVO result2 = new CusWhiteListEVO();
				OrgWhiteListEVO result3 = new OrgWhiteListEVO();
				//查询客户白名单表
				result2 = queryContractEleRs(wthldngCorpNm,reqContractEleAcqBean);
				if(!Objects.nonNull(result2) || result2.getIntRateRatio() == null) {
					//查询机构白名单表
					result3 = queryContractEleRs(wthldngCorpNm);
				}
				//查询客户信息表
				CusIndivVO result4 = queryContractEleRs(reqContractEleAcqBean);
				//查询授信协议表
				LmtPrdContVO result5 = queryLmtPrdContRs(reqContractEleAcqBean);
				//查询到的数据进行处理
				result = handleAllInfos(result1,result2,result3,result4,result5);
			}
			return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
					JSONObject.toJSONString(result,SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullStringAsEmpty),
					EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(),
					EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(), "合同要素查询完成。");
		} catch (BizException e) {
			logger.error("***********调用合同要素查询接口处理失败,"+e.getMessage() + "**************");
			return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
					JSONObject.toJSONString(result,SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullStringAsEmpty),
	                EsbSysHeadEnums.RetStEnum.FAILURE.getCode(),
	                e.getErrorCode(),
	                e.getMessage());
		} catch (Exception e) {
        	logger.error("***********调用合同要素查询接口处理失败,"+e.getMessage() + "**************");
			return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
					JSONObject.toJSONString(result),
					EsbSysHeadEnums.RetStEnum.FAILURE.getCode(),
					EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), e.getMessage());
		} finally {
			logger.info("***********合同要素查询接口处理结束授信申请流水号:"+lmtApplySeq);
			TraceUtil.clear();
		}
	}

	private RespContractEleAcqBean handleAllInfos(SOrgVO result1, CusWhiteListEVO result2, OrgWhiteListEVO result3,
                                                  CusIndivVO result4, LmtPrdContVO result5) throws ParseException {
		RespContractEleAcqBean result = new RespContractEleAcqBean();
		result.setCertTp("2");//授信额度循环标识1不可循环，2-循环,默认2循环
		result.setLoanTrm("Y");//贷款期限第1/2种值为：1/2,默认1按年
		result.setIntRtTp("2"); //税e贷固定“上浮” 1：下浮,2：上浮
		
		if(!Objects.isNull(result1)) {
			result.setBrchNm(result1.getOrgName());//分行名称
			result.setOrgPstCd(result1.getOrgZipcode());//机构邮政编码
			result.setOrgSite(result1.getOrgAddress());//机构地址
			result.setCorpTel(result1.getOrgTel());//机构联系电话
		}
		
		if(!Objects.isNull(result2)) {
			result.setUpFltIntRt(result2.getIntRateRatio() == null?"":result2.getIntRateRatio().toPlainString());//客户白名单上浮利率
		} else if(!Objects.isNull(result3)) {
			result.setUpFltIntRt(result3.getIntRateRatio() == null?"":result3.getIntRateRatio().toPlainString());//机构白名单上浮利率
		}
		
		if(!Objects.isNull(result4)) {
			result.setCustNm(result4.getCusName());//客户姓名
			result.setCertTp(result4.getCertType());//证件类型
			result.setCertNo(result4.getCertCode());//证件号码
			result.setResdntAddr(result4.getIndivRsdAddr());//客户住所
			result.setPstcd(result4.getPostCode());//客户邮政编码
			result.setCustFax(result4.getFaxCode());//客户传真
			result.setCtcTelNo(result4.getPhone());//客户联系电话
			result.setEmail(result4.getEmail());//电子邮箱
		}
		
		if(!Objects.isNull(result5)) {
			//将数字转化为中文大写
			result.setRMBCptl(Data2Zh.rmbChange(result5.getLmtAmt() == null?BigDecimal.ZERO:result5.getLmtAmt()));//人民币（大写）
			result.setRMBLwrcs(result5.getLmtAmt() == null?"":result5.getLmtAmt().toString());//人民币（小写）
			//
			String creStart = result5.getStartDate();
			if(!StringUtil.isNullorBank(creStart)) {
				if(DateTool.isDate(creStart)) {
					result.setCrdStrtYr(creStart.substring(0, 4));//授信开始年
					result.setCrdStrtMnth(creStart.substring(5, 7));//授信开始月
					result.setCrdStrtDay(creStart.substring(8, 10));//授信开始日
				}
			}
			//
			String creEnd = result5.getExpireDate();
			if(!StringUtil.isNullorBank(creEnd)) {
				if(DateTool.isDate(creEnd)) {
					result.setCrdEndYr(creEnd.substring(0, 4));//授信结束年
					result.setCrdEndMnth(creEnd.substring(5, 7));//授信结束月
					result.setCrdEndDay(creEnd.substring(8, 10));//授信结束日
				}
			}
			result.setCrdtDt(result5.getTerm() == null?"":result5.getTerm().toString());
			result.setLoanAcctNo(result5.getLoanAccount());//贷款账号
			result.setRpyAcctNo(result5.getRecvAccount());//还款账户
			result.setSgnDt(result5.getSignDate());//签约日期
		}
		return result;
	}

	private OrgWhiteListEVO queryContractEleRs(String wthldngCorpNm) {
		logger.info("开始查询机构白名单");
		OrgWhiteListEVO orgWhiteListEVO = new OrgWhiteListEVO();
		orgWhiteListEVO.setCompanyName(wthldngCorpNm);
		OrgWhiteListEVO result3 = orgWhiteListEService.queryContractEle(orgWhiteListEVO);
		if(Objects.nonNull(result3)) {
			logger.info("查询机构白名单结束，结果为：" + result3);
		} else {
			logger.info("查询机构白名单结束，结果为空");
		}
		return result3;
	}

	private CusWhiteListEVO queryContractEleRs(String wthldngCorpNm, ReqContractEleAcqBean reqContractEleAcqBean) {
		logger.info("开始查询客户白名单");
		CusWhiteListEVO cusWhiteListEVO = new CusWhiteListEVO();
		cusWhiteListEVO.setCompanyName(wthldngCorpNm);
		cusWhiteListEVO.setCertCode(reqContractEleAcqBean.getCertNo());
		cusWhiteListEVO.setCertType(reqContractEleAcqBean.getCertTp());
		CusWhiteListEVO result2 = cusWhiteListEService.queryContractEle(cusWhiteListEVO);
		if(Objects.nonNull(result2)) {
			logger.info("查询客户白名单结束，结果为：" + result2);
		} else {
			logger.info("查询客户白名单结束，结果为空");
		}
		return result2;
	}

	private SOrgVO queryOrgIdRs(String nlsOperOrgid) {
		logger.info("开始查询机构表");
		SOrgVO result1 = sOrgService.queryOrgId(nlsOperOrgid);
		if(Objects.nonNull(result1)) {
			logger.info("查询机构表结束，结果为：" + result1);
		} else {
			logger.info("查询机构表结束，结果为空");
		}
		return result1;
	}
	//查询授信申请表
	private String getnlsOperOrgid(ReqContractEleAcqBean reqContractEleAcqBean) {
		logger.info("开始查询授信申请表");
		String nlsOperOrgid = "";
		NlsCreditInfoVO nlsCreditInfoVO = new NlsCreditInfoVO();
		nlsCreditInfoVO.setLmtApplySeq(reqContractEleAcqBean.getCrdtAppFlowNo());
		nlsCreditInfoVO.setCusId(reqContractEleAcqBean.getClntNo());
		nlsCreditInfoVO.setCertType(reqContractEleAcqBean.getCertTp());
		nlsCreditInfoVO.setCertCode(reqContractEleAcqBean.getCertNo());
		NlsCreditInfoVO result1 = nlsCreditInfoService.queryContractEle(nlsCreditInfoVO);
		if(Objects.nonNull(result1)) {
			nlsOperOrgid = result1.getNlsOperOrgid();
			logger.info("查询授信申请表结束，结果为：" + result1);
		} else {
			logger.info("查询授信申请表结束，结果为空");
		}
		return nlsOperOrgid;
	}
	//查询客户信息表
	private CusIndivVO queryContractEleRs(ReqContractEleAcqBean reqContractEleAcqBean) {
		logger.info("开始查询客户信息表");
		CusIndivVO cusIndivVO = new CusIndivVO();
		cusIndivVO.setCusId(reqContractEleAcqBean.getClntNo());
		cusIndivVO.setCertType(reqContractEleAcqBean.getCertTp());
		cusIndivVO.setCertCode(reqContractEleAcqBean.getCertNo());
		CusIndivVO result4 = cusIndivService.queryContractEle(cusIndivVO);
		if(Objects.nonNull(result4)) {
			logger.info("查询客户信息表结束，结果为：" + result4);
		} else {
			logger.info("查询客户信息表结束，结果为空");
		}
		return result4;
	}
	//查询授信协议表
	private LmtPrdContVO queryLmtPrdContRs(ReqContractEleAcqBean reqContractEleAcqBean) {
		logger.info("开始查询授信协议表");
		LmtPrdContVO lmtPrdContVO = new LmtPrdContVO();
		lmtPrdContVO.setLmtApplySeq(reqContractEleAcqBean.getCrdtAppFlowNo());
		lmtPrdContVO.setCusId(reqContractEleAcqBean.getClntNo());
		lmtPrdContVO.setCertType(reqContractEleAcqBean.getCertTp());
		lmtPrdContVO.setCertCode(reqContractEleAcqBean.getCertNo());
		LmtPrdContVO result5 = lmtPrdContService.queryContractEle(lmtPrdContVO);
		if(Objects.nonNull(result5)) {
			logger.info("查询授信协议表结束，结果为：" + result5);
		} else {
			logger.info("查询授信协议表结束，结果为空");
		}
		return result5;
	}
	
	private String getWthldngCorpRgstTpNm(String wthldngAgntNo, String lmtApplySeq) throws Exception {
		String wthldngCorpNm = "";
		TaxWithholdRemitCorpVO taxWithholdRemitCorpVO = new TaxWithholdRemitCorpVO();
		taxWithholdRemitCorpVO.setWthldngTaxpyNo(wthldngAgntNo);
		taxWithholdRemitCorpVO.setCrdtAppFlowNo(lmtApplySeq);
		TaxWithholdRemitCorpVO queryTaxWithholdRemitCorpInfos = taxWithholdRemitCorpService.queryWthldngCorpNm(taxWithholdRemitCorpVO);
		if(Objects.isNull(queryTaxWithholdRemitCorpInfos)) {
			throw new Exception("根据扣缴义务人识别号："+ wthldngAgntNo +  "，未查询到代扣代缴单位名称。");
		}
		wthldngCorpNm = queryTaxWithholdRemitCorpInfos.getWthldngCorpNm();
		logger.info("根据扣缴义务人识别号："+ wthldngAgntNo + "，查询到代扣代缴单位名称为："+ wthldngCorpNm);
		return wthldngCorpNm;
	}
	
	private String getWthldngAgntNo(String lmtApplySeq) throws Exception {
		String wthldngAgntNo = "";
		TaxIncomeTaxInfoVO taxIncomeTaxInfoVO = new TaxIncomeTaxInfoVO();
		taxIncomeTaxInfoVO.setCrdtAppFlowNo(lmtApplySeq);
		TaxIncomeTaxInfoVO querytaxIncomeTaxInfos = taxIncomeTaxInfoService.queryWthldngAgntNo(taxIncomeTaxInfoVO);
		if(Objects.isNull(querytaxIncomeTaxInfos)) {
			throw new Exception("根据授信流水号："+ lmtApplySeq +  "，未查询到纳税信息。");
		}
		wthldngAgntNo = querytaxIncomeTaxInfos.getWthldngAgntNo();
		logger.info("根据授信流水号："+ lmtApplySeq + "，查询扣缴义务人识别号为："+ wthldngAgntNo);
		return wthldngAgntNo;
	}

	/**
	 * 
	 * TODO 判断该授信申请是不是该客户名下的授信<br>
	 * @author wanglihua
	 * @since 2019年5月22日 上午10:46:58
	 * @date 2019年5月22日 上午10:46:58
	 * @version 0.1 
	 */
	private boolean whetherCertEqual(NlsCreditInfoVO creditInfo, String certType, String certNo) throws Exception {
		logger.info("开始判断该授信申请是不是该客户名下的授信");
		boolean flag = false;
		if(certType.equals(creditInfo.getCertType()) && certNo.equals(creditInfo.getCertCode())) {
			flag = true;
		}
		logger.info("判断结束，结果为：" + flag);
		return flag;
	}
	
	private NlsCreditInfoVO queryCreditInfoRs(String lmtApplySeq) {
		logger.info("开始查找该授信申请");
		NlsCreditInfoVO nlsCreditInfoVO = new NlsCreditInfoVO();
		nlsCreditInfoVO.setLmtApplySeq(lmtApplySeq);
		NlsCreditInfoVO queryRsNlsCreditInfoVO = nlsCreditInfoService.queryByPk(nlsCreditInfoVO);
		logger.info("查找该授信申请结束");
		return queryRsNlsCreditInfoVO;
	}
}
